#include <board.h>
#include <board_memories.h>
#include <lcd/lcdd.h>
#include <lcd/draw.h>
#include <memories/MEDSdcard.h>
#include <ff.h>

static unsigned char *pLcdBuffer = (unsigned char *) (AT91C_EBI_SDRAM
        + 0x01000000);

#define _CHECK_FR(res, msg) \
    if (res != FR_OK) { \
        LCDD_DrawString(pLcdBuffer, 10, 221, msg, COLOR_RED); \
        return -1; \
    }

DWORD get_fattime( void )
{
    unsigned int date;

    date = ((2008 - 1980) << 25)
        | (01 << 21)
        | (14 << 16)
        | (WORD) (17 << 11)
        | (WORD) (16 << 5)
        | (WORD) (11 >> 1);

    return date;
}

Media sdcard;

static int x;

int list (int i, char* dirname) {
    FILINFO fi;
    DIR dir;
    FRESULT res;
    int r;

    res = f_chdir(dirname);
    _CHECK_FR(res, "- UPSIUPS!");
    res = f_opendir(&dir, ".");
    _CHECK_FR(res, "- DIR NOT OPENED!");

    upthere:
    while (i < BOARD_LCD_HEIGHT / 20 - 1) {
        res = f_readdir(&dir, &fi);
        _CHECK_FR(res, "- READ DIR IS NO MORE!");
        if (*(fi.fname) == '.') {
            continue;
        }
        if (*(fi.fname) == 0) {
            goto away;
        }
        LCDD_DrawString(pLcdBuffer, x, 1 + 20 * i, fi.fname, COLOR_BLACK);
        ++i;
        if (fi.fattrib & AM_DIR) {
            x += 4;
            r = list(i, fi.fname);
            if (r >= 0) {
                i = r;
            }
            x -=4;
        }
    }
    if ((x += (BOARD_LCD_WIDTH/2)) > BOARD_LCD_WIDTH) {
        goto away;
    }
    i = 0;
    goto upthere;

    away:
    res = f_chdir("..");
    _CHECK_FR(res, "- I AM ORFAN!");
    return i;
}

int main () {
    FATFS fs = {0};
    FRESULT res;

    // Initialize LCD
    LCDD_Fill(pLcdBuffer, COLOR_WHITE);
    LCDD_Initialize();
    LCDD_DisplayBuffer(pLcdBuffer);

#if !defined(sdram)
    BOARD_ConfigureSdram(BOARD_SDRAM_BUSWIDTH);
#endif

    MEDSdcard_Initialize(&sdcard, 0);

    // mount
    res = f_mount(DRV_MMC, &fs);
    _CHECK_FR(res, "- NOT MOUNTED!");

    res = f_chdrive(DRV_MMC);
    _CHECK_FR(res, "- NOT AT SD DRIVE!");

    x = 2;
    list(0, "0:");

    return 0;
}
